//
//  KKBLEService.m
//
//  Created by zorro on 2017/11/13.
//  Copyright © 2017年 zorro. All rights reserved.
//

#import "KKBLEService.h"
#import "KKBLEConnect.h"

// 2019.05.13添加硬件屏保图片
#define BLESERVICE [CBUUID UUIDWithString:@"8F400001-CFB4-14A3-F1BA-F61F35CDDBAF"]
#define BLESPEEDWRITE [CBUUID UUIDWithString:@"8F400004-CFB4-14A3-F1BA-F61F35CDDBAF"]  // 写
#define BLESPEEDNOTIFY [CBUUID UUIDWithString:@"8F400005-CFB4-14A3-F1BA-F61F35CDDBAF"] // 读

@interface KKBLEService ()

@property (nonatomic, strong) NSTimer                   *timer;
@property (nonatomic, strong) NSMutableData             *acceptData;
@property (nonatomic, assign) CBCharacteristicWriteType writeType;
@property (nonatomic, strong) CBCharacteristic          *readCharac;
@end

@implementation KKBLEService

DEF_SINGLETON(KKBLEService)

- (instancetype)init {
    self = [super init];
    if (self) {
        _acceptData = [[NSMutableData alloc] init];
        _writeType  = CBCharacteristicWriteWithResponse;
    }
    
    return self;
}

#pragma mark --- CBPeripheralDelegate ---
// 发现该设备所持有的所有服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    if (error) {
        NSLog(@"发生错误.");
    }
    
    CBUUID *serviceOTAUUID = [CBUUID UUIDWithString:SERVICE_OTA_UUID]; //指定服务
    
    for (CBService *service in peripheral.services) {
        // _service = [CBUUID UUIDWithString:@"8f400001-cfb4-14a3-f1ba-f61f35cddbaf"];
        if ([service.UUID isEqual:KK_BLEConfig.service]) {
            //BLESPEEDWRITE,BLESPEEDNOTIFY 2019.05.13 添加屏保的相关的写、读特征值
            [_peripheral discoverCharacteristics:@[KK_BLEConfig.write,
                                                   KK_BLEConfig.notify,BLESPEEDWRITE,BLESPEEDNOTIFY]
                                      forService:service];
        } else if ([service.UUID isEqual:KK_BLEConfig.updateService]) {
            // _updateService = [CBUUID UUIDWithString:@"00001530-1212-EFDE-1523-785FEABCD123"];
            [_peripheral discoverCharacteristics:@[KK_BLEConfig.updateControl,
                                                   KK_BLEConfig.updatePacket,
                                                   KK_BLEConfig.updateVersion]
                                      forService:service];
        } else if ([service.UUID isEqual:[CBUUID UUIDWithString:@"180A"]]) {
            [_peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:@"2A27"]] forService:service];
        } else if ([service.UUID isEqual:[CBUUID UUIDWithString:@"0xFF00"]]) {
            [_peripheral discoverCharacteristics:@[
                                                   [CBUUID UUIDWithString:@"0xFF01"],
                                                   [CBUUID UUIDWithString:@"0xFF01"]]
                                      forService:service];
        }
        
        //OTA
        if ([service.UUID isEqual:serviceOTAUUID]) {
            //外围设备查找指定服务中的特征
            [_peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:CHARACTERISTIC_OTA_WRITE_UUID], [CBUUID UUIDWithString:CHARACTERISTIC_OTA_INDICATE_UUID], [CBUUID UUIDWithString:CHARACTERISTIC_OTA_DATA_WRITE_UUID]] forService:service];
            //            [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:CHARACTERISTIC_OTA_WRITE_UUID], [CBUUID UUIDWithString:CHARACTERISTIC_OTA_INDICATE_UUID], [CBUUID UUIDWithString:CHARACTERISTIC_OTA_DATA_WRITE_UUID]] forService:service];
        }
        NSLog(@"service.UUID. = ...%@。%@", service, service.UUID.description);
    }
}

// 发现该服务所持有的所有特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if (error) {
        NSLog(@"特征错误...");
        // 发现错误时断开并重连接
    }
    for (CBCharacteristic *charac in service.characteristics) {
        if ([charac.UUID isEqual:KK_BLEConfig.notify]) {
            [_peripheral setNotifyValue:YES forCharacteristic:charac];
            if (_updateModelStatus) {
                _updateModelStatus(nil, KKBLEUpdateDidConnect);
            }
            NSLog(@"发现该服务所持有的所有特征--%@", charac.UUID);
            _isFoundChar = YES;
            [self delayConnectFinish];
//            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayConnectFinish) object:nil];
//            [self performSelector:@selector(delayConnectFinish) withObject:nil afterDelay:2.0];
        } else if ([charac.UUID isEqual:KK_BLEConfig.write]) {
            _readCharac = charac;
            NSLog(@"发现该服务所持有的所有特征--%@", charac.UUID);
        } else if ([charac.UUID isEqual:KK_BLEConfig.updateControl]) {
            [_peripheral setNotifyValue:YES forCharacteristic:charac];
        } else if ([charac.UUID isEqual:KK_BLEConfig.updatePacket]) {
        } else if ([charac.UUID isEqual:KK_BLEConfig.updateVersion]) {
        } else if ([charac.UUID isEqual: BLESPEEDWRITE]) {
            // 屏保 2019.05.13
            _readCharac = charac;
            NSLog(@">>>>>8F400004-CFB4-14A3-F1BA-F61F35CDDBAF");
        } else if ([charac.UUID isEqual:BLESPEEDNOTIFY]) {
            // 屏保 2019.05.13
            [_peripheral setNotifyValue:YES forCharacteristic:charac];
            NSLog(@">>>>>8F400005-CFB4-14A3-F1BA-F61F35CDDBAF");
        }
        else if ([charac.UUID isEqual:[CBUUID UUIDWithString:@"0xFF01"]]) {
            [_peripheral setNotifyValue:YES forCharacteristic:charac];
            if (_updateModelStatus) {
                _updateModelStatus(nil, KKBLEUpdateDidConnect);
            }
            // [self readBluetoothWrittenWay:charac.properties];
            // [_peripheral readValueForCharacteristic:charac];
            _readCharac = CBCharacteristicWriteWithResponse;
        }
    }
}

- (void)delayConnectFinish
{
     [self.send sendCMD]; //连接上蓝牙初始化
}

#pragma mark --- CBPeripheralDelegate 数据更新 ---
- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error {
    if (_updateModelStatus) {
        NSInteger rssi = ABS([RSSI integerValue]);
        KK_BLEModel.bleRSSI = [NSString stringWithFormat:@"%d", (int)rssi];
        _updateModelStatus(KK_BLEModel, KKBLEUpdateRSSI);
    }
}

- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error {
    if (_updateModelStatus) {
        NSInteger rssi = ABS([peripheral.RSSI integerValue]);
        KK_BLEModel.bleRSSI = [NSString stringWithFormat:@"%d", (int)rssi];
        _updateModelStatus(KK_BLEModel, KKBLEUpdateRSSI);
    }
}

// 向设备写数据时会触发该代理...
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
    if (error) {
        NSLog(@"写数据时发生错误...%@", error);
        if (!KK_BLEConnect.isUpdateing) {
            [peripheral discoverServices:@[KK_BLEConnect.config.service, [CBUUID UUIDWithString:@"0xFF00"]]];
        }
    }
}

// 外围设备数据有更新时会触发该方法
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
    if (error) {
        NSLog(@"数据更新错误...");
        //        [KK_BLEConnect disConnect];
        if (!KK_BLEConnect.isUpdateing) {
            [peripheral discoverServices:@[KK_BLEConnect.config.service, [CBUUID UUIDWithString:@"0xFF00"], [CBUUID UUIDWithString:SERVICE_OTA_UUID]]];
        }
    } else {
        // NSLog(@"..%@..%@", characteristic.value, characteristic.UUID);
        if ([characteristic.UUID isEqual:KK_BLEConfig.notify]) {
            [self cleanMutableData:_acceptData];
            [_acceptData appendData:characteristic.value];
            [_accept updateData:_acceptData updatePeripheral:peripheral];
        } else if ([characteristic.UUID isEqual:KK_BLEConfig.updateControl] ||
                   [characteristic.UUID isEqual:KK_BLEConfig.updatePacket]) {
        } else if ([characteristic.UUID isEqual:KK_BLEConfig.updateVersion]) {
            const uint8_t *version = [characteristic.value bytes];
        } else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"0xFF01"]]) {
            [self cleanMutableData:_acceptData];
            [_acceptData appendData:characteristic.value];
        } else if ([characteristic.UUID isEqual:BLESPEEDNOTIFY]) {
            [self cleanMutableData:_acceptData];
            [_acceptData appendData:characteristic.value];
            [_accept updateSpeedData:_acceptData updatePeripheral:peripheral];
            
        }
    }
}

#pragma mark --- receiveData 数据清空 ---
- (void)cleanMutableData:(NSMutableData *)data {
    [data resetBytesInRange:NSMakeRange(0, data.length)];
    [data setLength:0];
}

#pragma mark --- 向外围设备发送数据 ---
// 针对单连接
- (void)senderDataToPeripheral:(NSData *)data {
    //    NSLog(@"----写入数据 %@", data);
    if (_peripheral.state == CBPeripheralStateConnected) {
        CBUUID    *serviceUUID = KK_BLEConfig.service;
        CBUUID    *writeUUID   = KK_BLEConfig.write;
        CBService *service     = [self searchServiceFromUUID:serviceUUID withPeripheral:_peripheral];
        if (!service) {
            NSLog(@"service有错误...");
            return;
        }
        CBCharacteristic *chara = [self searchCharacteristcFromUUID:writeUUID withService:service];
        if (!chara) {
            NSLog(@"chara有错误...");
            return;
        }
        [_peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];
    }
}

- (void)senderDataToPeripheral64:(NSData *)data {
    if (_peripheral.state == CBPeripheralStateConnected) {
        CBUUID *serviceUUID = [CBUUID UUIDWithString:@"0xFF00"];
        CBUUID *charaUUID   = [CBUUID UUIDWithString:@"0xFF01"];
        UInt8  val[20]      = {0};
        [data getBytes:&val length:data.length];
        if (val[0] == 0x08) {
            charaUUID = [CBUUID UUIDWithString:@"00000af1-0000-1000-8000-00805f9b34fb"];
        }
        CBService *service = [self searchServiceFromUUID:serviceUUID withPeripheral:_peripheral];
        if (!service) {
            NSLog(@"service有错误...");
            return;
        }
        CBCharacteristic *chara = [self searchCharacteristcFromUUID:charaUUID withService:service];
        
        if (!chara) {
            NSLog(@"chara有错误...");
            return;
        }
        //NSLog(@"写入数据.>>>>>>>>>>>>.%@..%@", data, [BLTAcceptModel sharedInstance].updateValue);
        [_peripheral writeValue:data forCharacteristic:chara type:_writeType];
    }
}

// 针对多连接
- (void)senderDataToPeripheral:(NSData *)data withPeripheral:(CBPeripheral *)peripheral {
    if (peripheral.state == CBPeripheralStateConnected) {
        CBUUID    *serviceUUID = KK_BLEConfig.service;
        CBUUID    *writeUUID   = KK_BLEConfig.write;
        CBService *service     = [self searchServiceFromUUID:serviceUUID withPeripheral:peripheral];
        if (!service) {
            NSLog(@"service有错误...");
            return;
        }
        CBCharacteristic *chara = [self searchCharacteristcFromUUID:writeUUID withService:service];
        if (!chara) {
            NSLog(@"chara有错误...");
            return;
        }
        [peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];
        [NSThread sleepForTimeInterval:0.1f];
    }
}

// 匹配相应的服务
- (CBService *)searchServiceFromUUID:(CBUUID *)uuid withPeripheral:(CBPeripheral *)peripheral {
    for (int i = 0; i < peripheral.services.count; i++) {
        CBService *service = peripheral.services[i];
        if ([service.UUID isEqual:uuid]) {
            return service;
        }
    }
    return nil;
}

// 匹配相应的具体特征
- (CBCharacteristic *)searchCharacteristcFromUUID:(CBUUID *)uuid withService:(CBService *)service {
    for (int i = 0; i < service.characteristics.count; i++) {
        CBCharacteristic *chara = service.characteristics[i];
        if ([chara.UUID isEqual:uuid]) {
            return chara;
        }
    }
    return nil;
}

- (void)senderDataToPeripheralC1:(NSData *)data {
    if (_peripheral.state == CBPeripheralStateConnected) {
        NSLog(@"_peripheral.state.>>>%i", _peripheral.state);
        CBUUID    *serviceUUID = [CBUUID UUIDWithString:SERVICE_OTA_UUID];
        CBUUID    *writeUUID   = [CBUUID UUIDWithString:CHARACTERISTIC_OTA_WRITE_UUID];
        CBService *service     = [self searchServiceFromUUID:serviceUUID withPeripheral:_peripheral];
        if (!service) {
            NSLog(@"senderDataToPeripheralC1: service>>>错误");
            return;
        }
        CBCharacteristic *chara = [self searchCharacteristcFromUUID:writeUUID withService:service];
        if (!chara) {
            NSLog(@"senderDataToPeripheralC1: chara>>>错误");
            return;
        }
        [_peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];
    }
}

// 图片透传数据发送
- (void)senderSpeedDataToPeripheral:(NSData *)data {
    //    NSLog(@"高速蓝牙发送数据>>>>>%@",data);
    if (_peripheral.state == CBPeripheralStateConnected) {
        CBUUID    *serviceUUID = BLESERVICE;
        CBUUID    *writeUUID   = BLESPEEDWRITE;
        CBService *service     = [self searchServiceFromUUID:serviceUUID withPeripheral:_peripheral];
        if (!service) {
            return;
        }
        CBCharacteristic *chara = [self searchCharacteristcFromUUID:writeUUID withService:service];
        if (!chara) {
            return;
        }
        //目前
        //        [_peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];
        
        //CBCharacteristicWriteWithoutResponse
        [_peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithoutResponse];
        
    }
}

@end

